<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>this</title>
</head>

<body>

</body>

</html>
<script>
    var name = "222";
    var a = {
        name: '111',
        say: function () {
            console.log(this.name);
            console.log(this)
        }
    }
    var fun = a.say;
    fun() //   222
    a.say() // 111

    var b = {
        name: '333',
        say: function (fun) {
            fun()
        }
    }
    b.say(a.say); //222
    b.say = a.say
    b.say() ///333


    var num = (function (n) {
        if (n == 1) {
            return 1;
        }
        return n * arguments.callee(n - 1);
    })(10)


    var foo = '123'

    function print() {
        var foo = '456';
        this.foo = '789';
        console.log(foo)
    }
    print() //456

    var foo = 123

    function p() {
        this.foo = 234
        console.log(foo)
    }
    p() //234
    new p() // 123

    var a = 5;

    function test() {
        a = 0;
        console.log(a);
        console.log(this.a);
        var a;
        console.log(a)
    }
    test() //  0   5    0
    new test() //  0 undefine d 0

    // function prin(){
    //     console.log(foo);
    //     var foo = 2;
    //     console.log(foo);
    //     console.log(hrllo);
    // }
    // prin()  //hello is not defined


    function pri() {
        var test;
        test();

        function test() {
            console.log(1)
        }
    }
    pri()

    function pr() {
        var x = 1;
        if (x == "1") {
            console.log("One");
        }
        if (x === '1') {
            console.log("Two")
        }
    }
    pr()

    function prname() {
        var marty = {
            name: "marty",
            printName: function () {
                console.log(this.name);
            }
        }
        var test1 = {
            name: "test1"
        };
        var test2 = {
            name: "test2"
        };
        var test3 = {
            name: "test3"
        };
        test3.printName = marty.printName;
        var prinntName2 = marty.printName.bind({
            name: 123
        });
        marty.printName.call(test1);
        marty.printName.apply(test2);
        marty.printName();
        prinntName2();
        test3.printName();
    }
    prname()


    var bar = {
        a: '002'
    };

    function printnum() {
        bar.a = 'a';
        Object.prototype.b = 'b';
        return function inner() {
            console.log(bar.a);
            console.log(bar.b);
        }
    }
    printnum()()


    // 克隆
    const obj = {
        name: 'abc',
        age: 123,
        sex: 'female',
        card: ['visa', 'master'],
        wife: {
            name: 'bcd',
            son: {
                name: 'aaa'
            }
        }
    }

    var obj1 = {};

    // function clone(origin, target){
    //     let target = target || {};
    //     for(var prop in origin){
    //         target[prop] = origin[prop];
    //     }
    //     return target;
    // }
    // clone(obj, obj1)


    // 深度克隆
    /*
        遍历对象
        判断是不是原始值 typeof() object
        判断是数字还是对象 instanceof toString constructor 
        建立相应的数组或对象
        递归
     */
    function deepClone(origin, target) {
        var target = target || {};
        toStr = Object.prototype.toString,
            arrStr = "[object Array]";
        for (var prop in origin) {
            if (origin.hasOwnProperty(prop)) {

                if (origin[prop] !== 'null' && typeof (origin[prop]) == 'object') {

                    if (toStr.call(origin[prop]) == arrStr) {
                        target[prop] = [];
                    } else {
                        target[prop] = {};
                        
                    }
                    deepClone(origin[prop], target[prop]);
                } else {
                    target[prop] = origin[prop];
                }
            }
        }
        return target;
    }


</script>